#include "CMap.h"
#include "Wrappers\tinyxml.h"
#include "CLayer.h"
#include <string>
#include "Wrappers\CSGD_TextureManager.h"
#include "Game Objects\CTurret.h"
#include "Game Objects\CTeleporter.h"
#include "Messaging\CSGP_EventSystem.h"
#include "Wrappers\CSGD_DirectInput.h"
#include "Game Objects\CWorm.h"
#include "Game Objects\CSpider.h"
#include "Firewall.h"
#include "CDoor.h"
#include "console.h"

CMap::CMap(void)
{
	imageID = -1;
	currNode = NULL;
	CSGP_EventSystem::GetInstance()->RegisterClient("teleport", this);
}

CMap::~CMap(void)
{

	for(unsigned int i = 0; i < m_vNodes.size(); i++)
	{
		delete m_vNodes[i];
	}
	CSGP_EventSystem::GetInstance()->UnregisterClient("teleport", this);
	m_vNodes.clear();

}

bool CMap::Load(const char* szXmlFileName)
{
	TiXmlDocument doc;

	if(!doc.LoadFile(szXmlFileName))
		return false;

	TiXmlElement* pRoot = doc.RootElement();

	if(!pRoot)
		return false;

	TiXmlElement* pLayers = pRoot->FirstChildElement("Layer");
	if(!pLayers)
		return false;

	if(pLayers)
	{
		m_vNodes.push_back(new CNode);

		int i = 0;
		while(pLayers)
		{
			CLayer temp;
			int nDepth = -1;
			if(pLayers->Attribute("Depth", &nDepth))
			{
				temp.SetDepth(nDepth);
			}


			TiXmlElement* pTiles = pLayers->FirstChildElement("Tiles");

			if(pTiles)
			{
				TiXmlElement* pTile = pTiles->FirstChildElement("Tile");
				
				int j = 0;
				while(pTile)
				{
					temp.addTile();
					int nX = -1;
					if(pTile->Attribute("indexx", &nX))
					{
						temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetX(nX);
					}

					int nY = -1;
					if(pTile->Attribute("indexy", &nY))
					{
						temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetY(nY);
					}

					int mainX = -1;
					if(pTile->Attribute("mainx", &mainX))
					{
						temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetmX(mainX);
					}

					int mainY = -1;
					if(pTile->Attribute("mainy", &mainY))
					{
						temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetmY(mainY);

					}

					int nWidth = -1;
					if(pTile->Attribute("Width", &nWidth))
					{
						temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetWidth(nWidth);
					}

					int nHeight = -1;
					if(pTile->Attribute("Height", &nHeight))
					{
						temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetHeight(nHeight);

					}

					std::string nType;
					nType = pTile->Attribute("Type");
					
					if(strcmp(nType.c_str(), "normal" ) == 0)
							temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetType(0);

					if(strcmp(nType.c_str(), "player" ) == 0)
					{
						temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetType(2);
						CPlayer::GetInstance()->SetPosX((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmX() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetWidth());
						CPlayer::GetInstance()->SetPosY((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmY() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetHeight());
					}


					if(strcmp(nType.c_str(), "powerup" ) == 0)
					{
						temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetType(4);
						console tempc;
						tempc.SetPosX((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmX() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetWidth());
						tempc.SetPosY((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmY() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetHeight());
						m_vNodes[m_vNodes.size() - 1]->PushConsole(&tempc);
					}

					if(strcmp(nType.c_str(), "enemy" ) == 0)
					{
						int eid = -1;
						eid = atoi(pTile->Attribute("eid"));
						temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetType(3);

						if(eid == 0 || eid == -1)
						{
							CTurret tempt;
							tempt.SetPosX((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmX() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetWidth());
							tempt.SetPosY((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmY() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetHeight());
							tempt.SetMaxHealth(10);
							tempt.SetHealth(10);
							m_vNodes[m_vNodes.size() - 1]->PushEnemy(&tempt);
						}
						if(eid == 1)
						{
							CWorm tempw;
							tempw.SetPosX((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmX() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetWidth());
							tempw.SetPosY((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmY() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetHeight());
							tempw.SetMaxHealth(5);
							tempw.SetHealth(5);
							m_vNodes[m_vNodes.size() - 1]->PushEnemy(&tempw);

						}
						if(eid == 2)
						{
							CSpider temps;
							temps.SetPosX((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmX() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetWidth());
							temps.SetPosY((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmY() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetHeight());
							temps.SetMaxHealth(15);
							temps.SetHealth(15);
							m_vNodes[m_vNodes.size() - 1]->PushEnemy(&temps);
						}
						if(eid == 3)
						{
							CFirewall tempd;
							tempd.SetPosX((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmX() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetWidth());
							tempd.SetPosY((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmY() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetHeight());

							m_vNodes[m_vNodes.size() - 1]->PushEnemy(&tempd);

						}
						if(eid == 4)
						{
							CDoor tempf;
							tempf.setopen(false);
							tempf.SetPosX((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmX() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetWidth());
							tempf.SetPosY((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmY() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetHeight());
							m_vNodes[m_vNodes.size() - 1]->PushDoor(&tempf);
						}
					}


					if(strcmp(nType.c_str(), "teleport" ) == 0)
					{
						temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetType(1);

						CTeleporter temtele;
						temtele.setNode(m_vNodes[m_vNodes.size() - 1]);
						temtele.SetPosX((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmX() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetWidth());
						temtele.SetPosY((float)temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetmY() * temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetHeight());
						temtele.SetHeight(temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetHeight());
						temtele.SetWidth(temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->GetWidth());
						m_vNodes[m_vNodes.size() - 1]->PushTeleporter(&temtele);
					}

					temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->setdepth(nDepth);

					const char* szTrigger = pTile->GetText();
					if(szTrigger)
					{
						temp.GetTiles()->operator[](temp.GetTiles()->size() - 1)->SetTrigger(szTrigger);
					}

					j++;
					pTile = pTile->NextSiblingElement("Tile");
				}
			}


			i++;
			pLayers = pLayers->NextSiblingElement("Layer");
			m_vNodes[m_vNodes.size() - 1]->PushLayer(&temp);
		}
		if(imageID == -1)
		{
			std::string dir = ".\\Resource\\Graphics\\Art Assets\\";
			std::string filename; 
			filename = pRoot->FirstChildElement("filename")->GetText();
			dir.append(filename);
			imageID = CSGD_TextureManager::GetInstance()->LoadTexture(dir.c_str());
			
		}
		m_vNodes[m_vNodes.size() - 1]->SetImageID(imageID);
		m_vNodes[m_vNodes.size() - 1]->SetEffect(N_EFFECT(rand() % N_EFFECT_NUM_EFFECTS));
		//m_vNodes[m_vNodes.size() - 1]->SetEffect(N_EFFECT_ENEMIES);
		currNode = m_vNodes[0];

	}
	return true;
}

void CMap::render()
{
	currNode->Render();
	//for(unsigned int i = 0; i < m_vNodes.size(); i++)
	//{
	//	m_vNodes[i]->Render();
	//}
}
void CMap::update(float fElapsedTime)
{
	if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_F1) && currNode->GetOwner() == OWNER_AI)
		currNode->SetOwner(OWNER_PLAYER);

	if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_F2) && currNode->GetOwner() == OWNER_PLAYER)
		currNode->SetOwner(OWNER_AI);

	for(unsigned int i = 0; i < m_vNodes.size(); i++)
	{
		m_vNodes[i]->isplayerconnected = false;
		if(i == 0 && m_vNodes[0]->GetOwner() != OWNER_AI)
		{
			m_vNodes[0]->isplayerconnected = true;
			continue;
		}
		if(m_vNodes[i]->GetOwner() == OWNER_PLAYER)
		{
			for(unsigned int j = 0; j < m_vNodes[i]->getTeles()->size(); j++)
			{
				if(m_vNodes[i]->getTeles()->operator[](j)->getLink()->getNode()->isplayerconnected)
				{
					m_vNodes[i]->isplayerconnected = true;
					break;
				}
			}
		}
	}
	if(currNode->GetOwner() != OWNER_PLAYER)
	{
		for(unsigned int i = 0; i < currNode->getTeles()->size();i++)
			{
				if(currNode->getTeles()->operator[](i)->getLink()->getNode()->isplayerconnected)
				{
					currNode->isplayerconnected = true;
					break;
				}
			}
	}

	currNode->Update(fElapsedTime);
	//for(unsigned int i = 0; i < m_vNodes.size(); i++)
	//{
	//	m_vNodes[i]->Update(fElapsedTime);
	//}
}

void CMap::HandleEvent(CEvent* pEvnt)
{
	if(pEvnt->GetEventID() == "teleport" && m_vNodes.size() > 1)
	{
		currNode = (CNode*)pEvnt->GetParam();

	}
}

void CMap::killmap()
{
	for(unsigned int i = 0; i < m_vNodes.size(); i++)
	{
		delete m_vNodes[i];
	}
	m_vNodes.clear();
}


